package com.anolesoft.yr.mbus.code.service.gene;

import com.anolesoft.yr.mbus.code.dto.CodeItemDTO;
import com.anolesoft.yr.mbus.code.dto.CodeMainDTO;
import com.anolesoft.yr.mbus.code.entity.CodeMaxSequenceDO;
import com.anolesoft.yr.mbus.code.mapper.CodeMaxSequenceMapper;
import com.anolesoft.yr.util.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhj
 * @date 2020/9/25 9:20
 */
@Component("RelativeSequenceBuilder")
public class RelativeSequenceBuilder implements SequenceBuilder {
    @Autowired
    public RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private CodeMaxSequenceMapper codeMaxSequenceMapper;

    private final Lock lock = new ReentrantLock();

    @Override
    public String getSequence(CodeMainDTO codeMain, CodeItemDTO codeItem, String indiId) {
        lock.lock();
        try {
            String key = SequenceBuilder.builderKey(codeMain, indiId);
            Long increment = redisTemplate.opsForValue().increment(key, 1);
            saveSequence(codeMain, key);
            return increment.toString();
            //return redisTemplate.opsForValue().increment(SequenceBuilder.builderKey(codeMain, indiId), 1).toString();
        } finally {
            lock.unlock();
        }
    }

    private void saveSequence(CodeMainDTO codeMain, String key){
        Integer i = (Integer) redisTemplate.opsForValue().get(key);
        CodeMaxSequenceDO codeMaxSequence = codeMaxSequenceMapper.selectOneByCodeMainUidAndSequenceName(codeMain.getObjuid(), key);
        if(codeMaxSequence == null){
            codeMaxSequenceMapper.insert(CodeMaxSequenceDO.builder()
                    .codeItemUid("")
                    .codeMainUid(codeMain.getObjuid())
                    .maxSequence(i.longValue())
                    .objuid(CommonUtils.fastUUID())
                    .propertyValue("")
                    .sequenceName(key)
                    .build());
        }else{
            codeMaxSequence.setMaxSequence(i.longValue());
            codeMaxSequenceMapper.update(codeMaxSequence);
        }
    }
}
